from abc import ABC, abstractmethod
from typing import Any
from rasa_sdk.executor import CollectingDispatcher


class LLMAPI(ABC):
    def __init__(self):
        self.system_name = "system"
        self.max_content_length = 8192

    @abstractmethod
    def ask(self, events: list[dict[str, Any]], dispatcher: CollectingDispatcher) -> None:
        raise NotImplementedError

    @abstractmethod
    def optimize_response(self,
                          events: list[dict[str, Any]],
                          source_response: str,
                          dispatcher: CollectingDispatcher) -> None:
        raise NotImplementedError

    def generate_context(self, events: list[dict[str, Any]], base_context) -> list[dict[str, Any]]:

        content_length = 0

        for content in base_context:
            content_length += len(content["content"])

        context = []
        reversed_events = events[:-1]

        for event in reversed_events:
            print(event)
            if event["event"] == "user":
                if event["text"] is not None:
                    if content_length + len(event["text"]) <= self.max_content_length:
                        context.append(
                            {"role": "user", "content": event["text"]}
                        )
                    else:
                        break
            elif event["event"] == "bot":
                if event["text"] is not None:
                    if content_length + len(event["text"]) <= self.max_content_length:
                        context.append(
                                {"role": self.system_name, "content": event["text"]}
                            )
                    else:
                        break

        last_content = None

        if len(context) >= 1:
            last_content = context.pop()

        for content in base_context:
            context.append(content)

        if last_content is not None:
            context.append(last_content)

        return context
